#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

from abc import ABC, abstractmethod
import pwd

from common.const import RepositoryDataTypeEnum
from common.common import check_path_legal, check_sql_cmd_param
from generaldb.saphana.comm.common_util import log
from generaldb.saphana.comm.saphana_const import SaphanaJsonConstant, SaphanaPath
from common.parse_parafile import ParamFileUtil


class SaphanaParseJobParamsBase(ABC):
    # 该类定义为抽象基类，不能直接实例化
    def __init__(self, pid, job_id, subjob_id):
        self._pid = pid
        self._job_id = job_id
        self._subjob_id = subjob_id
        self._json_param = ""
        self._define_params = ""
        try:
            self._json_param = ParamFileUtil.parse_param_file(pid)
        except Exception as exception_str:
            raise Exception(f"Parse param file failed. pid:{pid} jobid:{job_id}") from exception_str
        if not self._json_param:
            raise Exception(f"json param is null. pid:{pid} jobid:{job_id}")

    def get_log_common(self):
        result = ""
        key_list = ["pid", "jobId", "subjobId"]
        index = 0
        for i in [self._pid, self._job_id, self._subjob_id]:
            if i:
                result = f"{result} {key_list[index]}:{i}"
            index += 1
        return result

    def get_maintask_id(self):
        return self._job_id

    def get_subtask_id(self):
        return self._subjob_id

    def get_copy_id(self):
        if not self._json_param:
            log.error(f"Json param is null. {self.get_log_common()}")
            return ""
        copy = self._json_param.get(SaphanaJsonConstant.JOB, {}).get(SaphanaJsonConstant().COPY, [])
        if not copy:
            log.error(f"Copy is null. {self.get_log_common()}")
            return ""
        # 备份copy只取第一个
        copy_id = copy[0].get(SaphanaJsonConstant.ID, "")
        if not copy_id:
            log.error(f"Get copy id  failed. {self.get_log_common()}")
        if not check_sql_cmd_param(copy_id):
            log.error(f"Copy id {copy_id} is illegal.")
            return ""
        return copy_id

    @abstractmethod
    def get_all_repositories(self):
        # 抽象方法子类必须实现
        pass

    def get_designated_path_ex(self, rep_type, repositories):
        if not repositories:
            log.error(f"Repositories is null. rep_type:{rep_type} {self.get_log_common()}")
            return ""
        for repository in repositories:
            if repository.get(SaphanaJsonConstant.REPOSITORY_TYPE, "") != rep_type:
                continue
            path_array = repository.get(SaphanaJsonConstant.PATH, [])
            if len(path_array) <= 0 or not path_array[0]:
                continue
            # 返回取到得路径中的第一个符合合法性校验的
            for path in path_array:
                if check_path_legal(path, SaphanaPath.HANA_LIVE_MOUNT_PATH):
                    return path
        log.error(f"Get path error. rep_type:{rep_type} {self.get_log_common()}")
        return ""

    def get_designated_path(self, rep_type):
        repositories = self.get_all_repositories()
        return self.get_designated_path_ex(rep_type, repositories)

    def get_cache_path(self):
        return self.get_designated_path(RepositoryDataTypeEnum.CACHE_REPOSITORY.value)

    def get_data_path(self):
        return self.get_designated_path(RepositoryDataTypeEnum.DATA_REPOSITORY.value)

    def get_meta_path(self):
        return self.get_designated_path(RepositoryDataTypeEnum.META_REPOSITORY.value)

    def get_log_path(self):
        return self.get_designated_path(RepositoryDataTypeEnum.LOG_REPOSITORY.value)

    def get_subjob_name(self):
        if not self._json_param:
            log.error(f"Json param is null. {self.get_log_common()}")
            return ""
        return self._json_param.get(SaphanaJsonConstant.SUB_JOB, {}).get(SaphanaJsonConstant.JOB_NAME, "")

    def get_query_permission(self):
        """
        返回query_job_permission任务的uid, gid
        """
        system_id = self._json_param.get(SaphanaJsonConstant.APPLICATION, {}).\
            get(SaphanaJsonConstant.EXTEND_INFO, {}).get(SaphanaJsonConstant.SYSTEM_ID, "")
        if system_id:
            return pwd.getpwnam(f"{system_id}adm").pw_uid, pwd.getpwnam(f"{system_id}adm").pw_gid
        return "", ""
